/*
 * Reaction.h
 *
 *  Created on: 21 Jul 2011
 *      Author: Allan
 */

#ifndef REACTION_H_
#define REACTION_H_

// C++ includes
#include <memory>

// Eigen includes
#include <Eigen/Core>
using namespace Eigen;

// GeoReact includes
#include "SpeciesMap.h"
#include "Utils.h"

class Reaction 
{
public:
	/// --- Auxiliary structures --- //
	struct Species
	{ String name; Index index; double stoichiometry; };
	
	struct EquilibriumConstantData
	{ DoubleVector logKi; DoubleVector Ti; };
	
public:
	Reaction();
	
	virtual ~Reaction() = 0;
	
	void
	SetReactant(const Species& reactant);
	
	void
	SetProducts(const vector<Species>& products);
	
	void
	SetEquilibriumConstantData(const EquilibriumConstantData& eqData);
	
	void
	SetSpeciesIndexes(const SpeciesMap& speciesMap);
	
	const Species&
	GetReactant() const;
	
	const vector<Species>&
	GetProducts() const;
	
	const EquilibriumConstantData&
	GetEquilibriumConstantData() const;
	
	const double
	EquilibriumConstant(double T, double P) const;
	
	const double
	ReactionQuotient(const DoubleVector& a) const;
	
	virtual const double
	ReactionMassRate(double T, double P, const DoubleVector& n, const DoubleVector& a) const = 0;
	
private:
	/// The reactant in the reaction
	Species reactant;
	
	/// The products in the reaction
	vector<Species> products;
	
	/// The equilibrium constants of the reaction over a set of temperature points
	EquilibriumConstantData eqData;
};

/// --- Auxiliary type definitions --- //
typedef std::shared_ptr<const Reaction> ReactionPtr;

/// --- Utility methods --- ///
const MatrixXd AssembleReactiveMatrix(const vector<ReactionPtr>& reactions, const StringVector& primarySpecies);

#endif /* REACTION_H_ */
